1 00:00:01,740 --> 00:00:06,780 Och, it's now time to start getting into the nitty gritty of coordinate frames. 2 00:00:06,870 --> 00:00:11,940 Now see, frames can be quite complex, so I'll try my best to explain them to you here and also leave 3 00:00:11,940 --> 00:00:14,310 some extra documentation by roadblocks on key frames. 4 00:00:14,310 --> 00:00:17,910 In case you didn't fully understand everything or you'd like to see more examples. 5 00:00:18,670 --> 00:00:21,640 The C frame contains two vector three objects. 6 00:00:21,640 --> 00:00:24,930 One represents the position and one represents the rotation. 7 00:00:24,940 --> 00:00:30,760 The position holds the global X, Y and Z coordinates, while the other represents the rotation data 8 00:00:30,760 --> 00:00:32,320 for each of the axes. 9 00:00:32,830 --> 00:00:37,870 The see frame object is also full of a bunch of neat functions that allow us to position parts relative 10 00:00:37,870 --> 00:00:38,800 to another part. 11 00:00:38,800 --> 00:00:42,880 Position parts between two other parts and rotate relative to another part. 12 00:00:43,510 --> 00:00:49,780 We can create a new C frame using the C frame new constructor, and we can either pass a vector three 13 00:00:50,020 --> 00:00:54,640 or three numbers to create and return a C frame that has no rotation. 14 00:00:55,330 --> 00:00:59,830 The constructor for See Frame, as you can notice, is overloaded, meaning that different parameters 15 00:00:59,830 --> 00:01:01,990 will result in different constructors being run. 16 00:01:02,140 --> 00:01:07,870 As another example, if you instead pass to vector threes, then this would return a C frame that has 17 00:01:07,870 --> 00:01:13,570 a position at this first vector three and a rotation that is facing towards the second vector three. 18 00:01:14,200 --> 00:01:19,930 There's also a function in C frame called look at, which is the same as this function here, but allows 19 00:01:19,930 --> 00:01:22,030 us to define one more vector three. 20 00:01:22,030 --> 00:01:25,720 And this vector three represents the up vector of the C frame. 21 00:01:25,720 --> 00:01:35,020 Or basically what direction is up to that C frame By default that is the vector 010, meaning that up 22 00:01:35,020 --> 00:01:38,710 is one unit towards the sky in the Y direction. 23 00:01:39,650 --> 00:01:44,480 There's another function called See Framed on angles, and this returns a C frame with a position of 24 00:01:44,480 --> 00:01:45,890 000. 25 00:01:45,890 --> 00:01:49,610 But it has a rotation that is based in radians. 26 00:01:49,610 --> 00:01:51,200 And we'll get to see this later. 27 00:01:52,370 --> 00:01:57,140 This last function I want to mention here is called lookup and that stands for linear interpolation. 28 00:01:57,140 --> 00:02:00,110 And that's kind of like another math function thing. 29 00:02:00,110 --> 00:02:07,490 But the basic idea of it is that you can create this imaginary line between two points and based on 30 00:02:07,490 --> 00:02:11,810 this line you can position your C frame to be on whatever point on the line. 31 00:02:12,950 --> 00:02:19,340 So the second number here represents a floating point number, and you can make it either zero all the 32 00:02:19,340 --> 00:02:20,240 way up to one. 33 00:02:20,240 --> 00:02:26,360 And that floating point number represents the percentage of distance away from this C frame is to the 34 00:02:26,360 --> 00:02:27,080 C frame. 35 00:02:27,350 --> 00:02:33,950 So if I put like 0.7, that would represent 70% of distance away from this C frame to the C frame. 36 00:02:36,100 --> 00:02:37,480 Okay, let's get started. 37 00:02:37,480 --> 00:02:39,250 Messing around with keyframes. 38 00:02:39,250 --> 00:02:41,250 So I have a variable here I created. 39 00:02:41,260 --> 00:02:42,990 It's just called demo and a reference. 40 00:02:43,000 --> 00:02:45,940 This folder I made in the workspace called C Frame Demo. 41 00:02:47,200 --> 00:02:49,600 And here, here's my little C frame demo. 42 00:02:49,930 --> 00:02:51,510 I have two red parts. 43 00:02:51,520 --> 00:02:53,410 One is called red one, the other is called red. 44 00:02:53,410 --> 00:02:56,460 Two, I have this blue part with a decal on it. 45 00:02:56,470 --> 00:03:00,630 And this decal is facing in the forward facing direction for this part. 46 00:03:00,640 --> 00:03:06,880 So if I right click my part and press this button that says Show orientation indicator, I can see which 47 00:03:06,880 --> 00:03:08,230 direction this part is facing. 48 00:03:08,230 --> 00:03:10,090 This is the front face for the part. 49 00:03:12,320 --> 00:03:16,940 Now, what I'm going to do here is I'm going to have this part become rotated and face towards this 50 00:03:16,940 --> 00:03:20,420 first read part here so I can go into my script. 51 00:03:21,350 --> 00:03:24,170 And I can create a new frame and I'll store it in a variable. 52 00:03:24,170 --> 00:03:26,540 Just call it looking see frame. 53 00:03:28,290 --> 00:03:32,250 And I'll set it to a new frame using the dot new constructor. 54 00:03:33,890 --> 00:03:37,400 And I'll first pass the position of my blue part. 55 00:03:38,990 --> 00:03:45,770 I'm just indexing my reference to the folder, getting blue and getting the position property. 56 00:03:45,860 --> 00:03:46,370 Whoops. 57 00:03:47,830 --> 00:03:52,630 And then the second parameter here, I'm going to set it to be the position of my read part. 58 00:03:55,270 --> 00:03:59,860 So what this is saying is I'm returning a see frame that has the position that's the same as my blue 59 00:03:59,860 --> 00:04:03,400 part, but it has a rotation that is looking at my red part. 60 00:04:03,700 --> 00:04:09,280 And then now I can index to get my blue part and I can override it. 61 00:04:09,310 --> 00:04:11,860 See frame with this new frame I made. 62 00:04:13,570 --> 00:04:14,950 Now I can run my game. 63 00:04:17,080 --> 00:04:20,740 And I should be able to see this part rotate and look towards my red part. 64 00:04:22,010 --> 00:04:22,730 Perfect. 65 00:04:24,960 --> 00:04:27,960 I can also perform some arithmetic on the C frame. 66 00:04:28,200 --> 00:04:34,260 So, for example, maybe I wanted to move my part where it's looking at this red object and then move 67 00:04:34,260 --> 00:04:36,120 like five studs towards it. 68 00:04:36,780 --> 00:04:40,520 To do that, I can create a new variable. 69 00:04:40,530 --> 00:04:43,470 I'll call it looking see frame moved. 70 00:04:44,430 --> 00:04:48,330 And I'll take my looking C frame and I'll offset it. 71 00:04:49,530 --> 00:04:56,490 By the look and see frames look vector and what the look vector returns is a vector that has a distance 72 00:04:56,490 --> 00:04:57,030 of one. 73 00:04:57,030 --> 00:05:03,270 The line has a magnitude of one, and it's the direction of where my vector is facing. 74 00:05:05,490 --> 00:05:09,870 In this case, when I rotate it, it'll be facing in some direction that's going towards my part. 75 00:05:10,720 --> 00:05:12,580 And it'll move it by one stud. 76 00:05:12,580 --> 00:05:17,800 If I want to move it more than one stud, then I can multiply this vector by a number and that will 77 00:05:17,800 --> 00:05:18,480 be in stud. 78 00:05:18,490 --> 00:05:19,780 So maybe I want to move it. 79 00:05:19,780 --> 00:05:20,950 Five studs. 80 00:05:22,060 --> 00:05:24,580 Then I can yield for like 3 seconds. 81 00:05:24,670 --> 00:05:27,730 Otherwise, if I don't yield, this will execute immediately. 82 00:05:27,730 --> 00:05:30,490 And then me setting the new frame will execute immediately. 83 00:05:30,490 --> 00:05:32,170 So I won't be able to see the change. 84 00:05:33,120 --> 00:05:39,420 We're just going to yield and I'll override the frame of my blue part again to this new looking C frame 85 00:05:39,420 --> 00:05:40,040 moved. 86 00:05:41,470 --> 00:05:42,790 Now if I run my game. 87 00:05:44,600 --> 00:05:49,220 It looks at my part and then it should move five studs towards my part just like that. 88 00:05:49,530 --> 00:05:49,530 I. 89 00:05:50,360 --> 00:05:54,500 I can also offset my part in many other directions, such as in the Y direction. 90 00:05:54,500 --> 00:05:56,910 So maybe I want to move my part upwards. 91 00:05:56,930 --> 00:05:59,300 Then I can yield again. 92 00:06:03,450 --> 00:06:07,560 And then I can override the C frame to the same looking C frame moved. 93 00:06:09,010 --> 00:06:14,310 And instead, now I want to move it up in the Y direction by, let's say, ten studs. 94 00:06:14,320 --> 00:06:22,510 So I'll create a new vector, three object new, and this will just go ten studs up in the Y direction. 95 00:06:23,750 --> 00:06:25,190 Now if I run my game again. 96 00:06:26,530 --> 00:06:29,980 I look at my part should move five studs towards my part. 97 00:06:31,030 --> 00:06:32,620 And then move up ten studs. 98 00:06:33,070 --> 00:06:33,820 Awesome. 99 00:06:35,430 --> 00:06:41,010 Now I can also mess with the angles of my part by messing with the angles of the C frame. 100 00:06:41,010 --> 00:06:42,680 So I'll create another variable. 101 00:06:42,690 --> 00:06:50,760 I'll just call it rotated see frame and I'll set it to a new C frame object and I'll use the angles 102 00:06:50,760 --> 00:06:51,450 function. 103 00:06:51,960 --> 00:06:56,820 Now, in here I need to pass three numbers and these numbers have to be in radians. 104 00:06:57,150 --> 00:07:01,620 And basically, if you don't know what a radiant is, it's the distance around a circle. 105 00:07:01,620 --> 00:07:04,320 So it starts off at like zero. 106 00:07:04,620 --> 00:07:08,880 And then halfway around the circles pi and then all the way around the circle is two pi. 107 00:07:08,880 --> 00:07:12,420 And this is kind of stuff you'll learn in trigonometry if you ever did trigonometry. 108 00:07:12,780 --> 00:07:16,410 And those radians have the same kind of equivalent in degrees. 109 00:07:16,410 --> 00:07:22,170 So like 30 degrees around a circle has this same circumference in radians. 110 00:07:22,170 --> 00:07:23,790 That's just what radians stands for. 111 00:07:24,240 --> 00:07:27,590 But I don't expect you to know radians off the top of your head. 112 00:07:27,600 --> 00:07:33,240 So we have this cool function called math dot rad and I'll convert degrees into radians. 113 00:07:33,450 --> 00:07:41,370 So maybe I want to rotate like 180 degrees around the x axis and then maybe I want to rotate, I don't 114 00:07:41,370 --> 00:07:44,280 know, 55 degrees around the Y axis. 115 00:07:44,280 --> 00:07:47,760 And then maybe I want to rotate -90 degrees around the Z axis. 116 00:07:47,760 --> 00:07:49,110 We'll just do something like that. 117 00:07:49,800 --> 00:07:58,170 I will yield again for 3 seconds and then I will override the C frame of my blue part once more to this 118 00:07:58,170 --> 00:07:59,640 new rotated C frame. 119 00:08:00,120 --> 00:08:04,830 Now the problem is, is that this new rotated C frame doesn't have a position. 120 00:08:05,310 --> 00:08:07,350 The default position is 000. 121 00:08:07,350 --> 00:08:12,630 So this blue C frame, this blue object is going to move all the way to the origin point of my map. 122 00:08:12,630 --> 00:08:13,500 And I don't want to do that. 123 00:08:13,500 --> 00:08:16,440 I want to keep the same position, just rotate it randomly. 124 00:08:17,130 --> 00:08:23,910 So to do that I can get my C frame and multiply it by this rotated C frame. 125 00:08:23,910 --> 00:08:28,710 So basically what I'm doing is I'm adding this rotation to my C frame. 126 00:08:28,710 --> 00:08:29,940 That's just the position. 127 00:08:30,540 --> 00:08:32,850 And we use the multiplication operator here. 128 00:08:32,850 --> 00:08:38,340 So when you want to offset C frames with another C frame, use the multiplication operator. 129 00:08:38,460 --> 00:08:43,620 But if you want to offset a C frame using a vector, then you have to use the addition operator. 130 00:08:44,810 --> 00:08:46,940 So let me run my game and let's see if this works. 131 00:08:48,410 --> 00:08:51,380 So I look at it, I should move five studs towards it. 132 00:08:51,800 --> 00:08:53,180 Move ten studs up. 133 00:08:54,030 --> 00:08:56,220 And then I should rotate some random amount. 134 00:08:57,790 --> 00:08:58,310 Here we go. 135 00:08:58,330 --> 00:09:00,070 There's my weird rotation. 136 00:09:01,350 --> 00:09:06,480 Now, the last thing I want to show you here is linear interpolation, and I explained it briefly earlier, 137 00:09:06,630 --> 00:09:11,640 but like I said, it's kind of an invisible line between two points that you can place a C frame on. 138 00:09:11,940 --> 00:09:17,940 So my game, I want to position this blue object between these two red objects, somewhere between these 139 00:09:17,940 --> 00:09:18,990 two red objects. 140 00:09:19,110 --> 00:09:25,440 So imagine an invisible line going from this object to this object, and I can put this blue object 141 00:09:25,440 --> 00:09:31,680 somewhere on that line and the percentage denotes how far away from this object I want to be to this 142 00:09:31,680 --> 00:09:32,240 object. 143 00:09:32,250 --> 00:09:37,830 So if I do like 0.2, it'll be 20% of the way to this object. 144 00:09:38,040 --> 00:09:40,260 So 0.2 would be like, right here. 145 00:09:40,470 --> 00:09:42,480 And if I do 0.5, that's halfway. 146 00:09:42,480 --> 00:09:43,890 So it'll be at the halfway mark. 147 00:09:43,900 --> 00:09:47,490 And if I do 0.9, then it'll be almost right next to this last part. 148 00:09:47,910 --> 00:09:51,510 And then one would mean it's in the exact same position as this part. 149 00:09:52,280 --> 00:09:53,600 So let's show that real quick. 150 00:09:53,690 --> 00:09:59,960 I'm going to index the demo folder and get my first read part and get it see frame. 151 00:10:00,230 --> 00:10:05,480 And then using the C frame I can call the lookup function and pass another C frame. 152 00:10:05,480 --> 00:10:08,900 The other C frame is going to be my second read object. 153 00:10:10,140 --> 00:10:14,130 So basically this is my starting see frame and this is my goal see frame. 154 00:10:15,380 --> 00:10:20,300 And then I can pass a floating point number to define what percentage of the way I want to make to my 155 00:10:20,300 --> 00:10:21,150 second keyframe. 156 00:10:21,170 --> 00:10:24,170 So for this example, I'll just do point five, which is halfway. 157 00:10:25,380 --> 00:10:27,770 And then I can store the results of this in a variable. 158 00:10:27,780 --> 00:10:29,670 I'll just call it to see frame. 159 00:10:31,930 --> 00:10:39,130 I will yield once more for 3 seconds and then I'll override the key frame of my blue part again. 160 00:10:39,220 --> 00:10:41,440 To this new looped C frame. 161 00:10:43,120 --> 00:10:44,260 Let me run my game. 162 00:10:45,790 --> 00:10:46,030 Okay. 163 00:10:46,030 --> 00:10:47,290 We look at our object. 164 00:10:47,470 --> 00:10:49,310 We move five studs to it. 165 00:10:49,330 --> 00:10:51,070 We should move ten studs up. 166 00:10:52,080 --> 00:10:53,760 Well, rotate randomly. 167 00:10:54,790 --> 00:10:55,450 Cool. 168 00:10:55,600 --> 00:10:58,330 And then we should move between these two objects. 169 00:10:58,540 --> 00:10:59,290 Awesome. 170 00:10:59,740 --> 00:11:02,590 Now, if you've noticed, we lost our rotation. 171 00:11:02,590 --> 00:11:04,150 How do we keep our rotation? 172 00:11:04,570 --> 00:11:05,530 I'll show you real quick. 173 00:11:06,100 --> 00:11:08,470 So where we set our C frame? 174 00:11:08,470 --> 00:11:13,330 Unfortunately, when you use this function, it returns a C frame with no rotation. 175 00:11:13,330 --> 00:11:19,030 So to preserve our rotation, I'll just multiply it again by our rotated C frame. 176 00:11:19,210 --> 00:11:21,700 That way we keep our rotation. 177 00:11:22,550 --> 00:11:27,890 Another thing you might have noticed is actually we can clean up this line right here because we are 178 00:11:27,890 --> 00:11:30,800 setting the C frame to itself. 179 00:11:30,800 --> 00:11:37,760 Times this rotated C frame, we can actually just use the multiply equal operator and it achieves the 180 00:11:37,760 --> 00:11:38,660 same effect. 181 00:11:39,560 --> 00:11:43,010 Now, if I run my game again, we should preserve our rotation. 182 00:11:56,230 --> 00:11:57,100 Perfect. 183 00:11:57,670 --> 00:11:59,530 So everything worked out nicely. 184 00:12:01,030 --> 00:12:05,740 So this was just a quick and brief overview of how to use see frames and roadblocks. 185 00:12:06,220 --> 00:12:11,620 If you're confused on something still or you need more help, feel free to check out that robot's article 186 00:12:11,620 --> 00:12:12,090 link. 187 00:12:12,100 --> 00:12:14,200 Or don't be afraid to ask any questions.